<?php
// $Id: Initializer.php 27 2010-11-16 12:49:54Z mjohnson60@gmail.com $

/**
 * User: Titan
 * Date: Sep 28, 2010
 * Time: 5:29:23 PM
 */

require_once(ROOT . '/libraries/Object.php');
require_once(ROOT . '/libraries/File.php');
require_once(ROOT . '/libraries/Folder.php');
require_once(ROOT . '/libraries/Loader.php');

/**
 * The stages of the system's load and launch
 */
// This stage loads any necessary configuration data and other useful variables
define('INITIALIZE_CONFIGURATION', 0);

// This stage loads the database connections and functions
define('INITIALIZE_DATABASE', 1);

// This stage creates a user session, which is useful for form verification
define('INITIALIZE_SESSION', 2);

// This stage initializes database caching system
define('INITIALIZE_CACHE', 3);

// This stage checks the request URI and loads the appropriate file for the request
define('INITIALIZE_ROUTER', 4);

// This stage loads any functions necessary for rendering output, creating forms, and handling
// database objects
define('INITIALIZE_SYSTEM', 5);

// This stage loads any extra variables sent to the system via the query string and stores them
// for othere functions to use
define('INITIALIZE_FULL', 6);

/**
 * Role ID for anonymous users; should match what's in the "role" table.
 */
define('HERMES_ANONYMOUS_RID', 1);

/**
 * Role ID for authenticated users; should match what's in the "role" table.
 */
define('HERMES_AUTHENTICATED_RID', 2);

/**
 * Indicates that the item should never be removed unless explicitly told to
 * using cache_clear_all() with a cache ID.
 */
define('CACHE_PERMANENT', 0);

/**
 * Indicates that the item should be removed at the next general cache wipe.
 */
define('CACHE_TEMPORARY', -1);

/**
 * Indicates that page caching is disabled.
 */
define('CACHE_DISABLED', 0);

/**
 * Indicates that page caching is enabled, using "normal" mode.
 */
define('CACHE_NORMAL', 1);

/**
 * Log message severity -- Emergency: system is unusable.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_EMERG', 0);

/**
 * Log message severity -- Alert: action must be taken immediately.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_ALERT', 1);

/**
 * Log message severity -- Critical: critical conditions.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_CRITICAL', 2);

/**
 * Log message severity -- Error: error conditions.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_ERROR', 3);

/**
 * Log message severity -- Warning: warning conditions.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_WARNING', 4);

/**
 * Log message severity -- Notice: normal but significant condition.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_NOTICE', 5);

/**
 * Log message severity -- Informational: informational messages.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_INFO', 6);

/**
 * Log message severity -- Debug: debug-level messages.
 *
 * The WATCHDOG_* constant definitions correspond to the logging severity levels
 * defined in RFC 3164, section 4.1.1: http://www.faqs.org/rfcs/rfc3164.html
 *
 * @see messages()
 * @see messages_severity_levels()
 */
define('WATCHDOG_DEBUG', 7);

/**
 * Role ID for anonymous users; should match what's in the "role" table.
 */
define('USER_ANONYMOUS_RID', 1);

/**
 * Role ID for authenticated users; should match what's in the "role" table.
 */
define('USER_AUTHENTICATED_RID', 2);

/**
 * RENDER TYPES
 */

/**
 * This render type suggests that an enabled module is either creating a new
 * object to render or overriding the system rendering method.
 */
define('RENDER_TYPE_MODULE', 0);

/**
 * This render type implies that the active theme is overriding the system and
 * any enabled modules.
 */
define('RENDER_TYPE_THEME_ENGINE', 1);

/**
 * This render type implies that the active theme is overriding the system and
 * any enabled modules.
 */
define('RENDER_TYPE_BASE_THEME', 2);

/**
 * This render type implies that the active theme is overriding the system and
 * any enabled modules.
 */
define('RENDER_TYPE_THEME', 3);

/**
 * This render type implies that the currently active path is overriding
 * everything else.
 */
define('RENDER_TYPE_PATH', 4);

/**
 * Config defaults
 */
define('HERMES_MINIMUM_PHP', '4.3.5');

/**
 * Enter description here ...
 * 
 * @author Mark Phillip Johnson
 * @version 1.0
 * @copyright Copyright (c) 2010, markjohnson
 * @license http://www.gnu.org/licenses/gpl.html The GNU General Public License v3.0
 *
 */
final class Initializer extends Object
{
	/**
	 * @var Initializer Enter description here ...
	 */
	private static $instance = NULL;
	
	/**
	 * @var int Enter description here ...
	 */
	private static $phase = INITIALIZE_CONFIGURATION;

	/**
	 * __construct()
	 * 
	 * Enter description here ...
	 * 
	 */
	public function __construct()
	{
		self::$instance =& $this;
	}

	/**
	 * getInstance()
	 * 
	 * Enter description here ...
	 * 
	 * @return Initializer
	 */
	public static function &getInstance()
	{
		if (!isset(self::$instance))
		{
			new Initializer();
		}
		
		return self::$instance;
	}
	
	/**
	 * phase()
	 * 
	 * Enter description here ...
	 * 
	 * @return number
	 */
	public static function phase() 
	{
		return self::$phase;
	}
	
	/**
	 * hooks()
	 * 
	 * Enter description here ...
	 * 
	 * @return array 
	 */
	public static function hooks() 
	{
		return array('boot', 'exit');
	}

	/**
	 * initialize()
	 *
	 * Initialize the entire system for use.
	 *
	 * @param mixed $phase
	 * @return void
	 */
	public static function initialize($phase = INITIALIZE_SYSTEM)
	{
		self::$phase = $phase;
		
		if (self::$phase >= INITIALIZE_CONFIGURATION) 
		{
			Initializer::initializeConfiguration();
		}
	}

	/**
	 * initialize_configuration()
	 *
	 * sets up a few useful variables for use with forms, links, and other things
	 *
	 * @return void
	 */
	public static function initializeConfiguration()
	{
		Loader::import('Config');
		Config::init();
		
		if (self::$phase > INITIALIZE_CONFIGURATION)
		{
			Initializer::initializeDatabase();
		}
	}

	/**
	 * initialize_database()
	 *
	 * Load the database connections and query functions
	 *
	 * @return void
	 */
	public static function initializeDatabase()
	{
		Loader::import('Db');
		
		Db::init();
		
		if (self::$phase > INITIALIZE_DATABASE)
		{
			Initializer::initializeSession();
		}
	}

	/**
	 * initializeSession()
	 * 
	 * Enter description here ...
	 * 
	 */
	public static function initializeSession()
	{
		// initialize a session for the current user
		include_once('./includes/session.inc');
		//include_once('./includes/user.inc');
		session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy_sid', 'sess_gc');
		session_start();
		
		if (self::$phase > INITIALIZE_SESSION)
		{
			Initializer::initializeCache();
		}
	}

	/**
	 * initializeCache()
	 * 
	 * Enter description here ...
	 * 
	 * @param unknown_type $skipModules
	 */
	public static function initializeCache($skipModules = FALSE)
	{
		Loader::import('Storage');
		Storage::init();
				
		if (!$skipModules) 
		{
			Initializer::_initializeModules();
		}
		
		page_header();
		
		if (self::$phase > INITIALIZE_CACHE)
		{
			Initializer::initializeRouter();
		}
	}

	/**
	 * _initializeModules()
	 * 
	 * Enter description here ...
	 * 
	 */
	public static function _initializeModules()
	{
		Loader::import('Moduler');
		
		Moduler::loadAll();
		
		Initializer::_initializeAll('boot');
	}

	/**
	 * _initializeAll()
	 * 
	 * Enter description here ...
	 * 
	 * @param unknown_type $hook
	 */
	public static function _initializeAll($hook)
	{
		foreach (Moduler::moduleList(TRUE, TRUE) as $module)
		{
			Athena::loadFile('module', $module);
			Moduler::invokeStatic($module, $hook);
		}
	}

	/**
	 * initialize_router()
	 *
	 * Checks the request URI and loads the appropriate file for the request
	 *
	 * @return void
	 */
	public static function initializeRouter()
	{
		Loader::import('Router');
		
		Router::init();
		
		if (self::$phase > INITIALIZE_ROUTER)
		{
			Initializer::initializeSystem();
		}
	}

	/**
	 * initialize_system()
	 *
	 * Loads functions that are critical to rendering output, creating forms, and creating database objects
	 *
	 * @return void
	 */
	public static function initializeSystem()
	{
		include_once ('./includes/unicode.inc');
		Loader::import('Theme');
		Loader::import('Batch');
		Loader::import('Renderer');
		Loader::import('Form');
		Loader::import('Dispatcher');
		Loader::import('Html');
		Loader::import('Log');
		Loader::import('Controller');
		
		if (self::$phase > INITIALIZE_SYSTEM)
		{
			Initializer::initializeFull();
		}
	}

	/**
	 * initialize_full()
	 *
	 * Loads any extra query string variables
	 *
	 * @param mixed $vars
	 * @return void
	 */
	public static function initializeFull()
	{
		parse_str($_SERVER['QUERY_STRING'], $query_string);
		unset($query_string['q']);
		
		if (!empty($query_string))
		{
			$vars['query'] = $query_string;
			
			if (isset($vars['query']['op']))
			{
				if (isset($vars['path']))
				{
					$vars['path']->op = $vars['query']['op'];
					
					if (isset($vars['query']['subop']))
					{
						$vars['path']->op = $vars['query']['subop'];
					}
				}
				else
				{
					$GLOBALS['op'] = $vars['query']['op'];
					
					if (isset($vars['query']['subop']))
					{
						$GLOBALS['subop'] = $vars['query']['subop'];
					}
				}
			}
		}
		
		if ($_SERVER['REQUEST_METHOD'] == 'POST' && FALSE)
		{
			$form_state = form_process_submitted_form($_POST);
			
			$vars['form_state'] = $form_state;
		}
		
		Moduler::loadAll();
		if (!defined('CONFIGURATION_MODE') || CONFIGURATION_MODE != 'UPDATE')
		{
			Moduler::invokeAll('init');
		}
	}
}
